package cn.wen.forum.service.impl;

import cn.wen.forum.common.enums.ResultCode;
import cn.wen.forum.common.result.JSONResult;
import cn.wen.forum.common.result.Result;
import cn.wen.forum.common.util.LevelUtils;
import cn.wen.forum.common.util.RedisUtils;
import cn.wen.forum.common.util.StringUtils;
import cn.wen.forum.config.JWTConfig;
import cn.wen.forum.constants.ForumConstant;
import cn.wen.forum.mapper.PostMapper;
import cn.wen.forum.mapper.ReviewMapper;
import cn.wen.forum.mapper.UserMapper;
import cn.wen.forum.pojo.entity.Post;
import cn.wen.forum.pojo.entity.Review;
import cn.wen.forum.pojo.entity.User;
import cn.wen.forum.service.IReviewService;
import cn.wen.forum.vo.ReviewVO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName ReviewService
 * @Author By wen
 * @Description 评论表 服务层
 * @Date 2023/8/3 16:20
 * @Version 1.0
 */
@Service("review")
public class ReviewService extends ServiceImpl<ReviewMapper, Review> implements IReviewService {

    @Autowired
    private PostMapper postMapper;

    @Autowired
    private ReviewMapper reviewMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    public RedisUtils redisUtils;


    /**
     * 获取评论list
     *
     * @param id
     * @return
     */
    @Override
    public JSONResult getReviewListById(String id) {
        List<ReviewVO> reviews = reviewMapper.selectReviewAndUserHead(id);
        // 获取所有的一级评论（root）
        List<ReviewVO> rootReviews = reviews.stream().filter(review1 -> review1.getParentId() == 0).collect(Collectors.toList());
        for(ReviewVO rootReview:rootReviews) {
            // 筛选所有评论的父评论为当前root评论的数据
            List<ReviewVO> reviewList = reviews.stream()
                    .filter(review2 -> review2.getParentId().equals(rootReview.getId()))
                    .collect(Collectors.toList());

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            rootReview.setTimeStr(dateFormat.format(rootReview.getTime()));
            for (ReviewVO reviewVO : reviewList) {
                reviewVO.setTimeStr(dateFormat.format(reviewVO.getTime()));
                reviewVO.setLevelStr(LevelUtils.levelToLevelName(reviewVO.getLevel()));
                //1. 获取评论中回复哪个评论的id的集合，用来步骤3中设置头像以及用户名称信息。
               /* List<ReviewVO> parentReview
                        = reviews.stream()
                        // 获取所有的评论的回复id也就是父级id的userid，这样就可以获取到父级评论的信息
                        .filter(review4 -> reviewVO.getAnswerId().equals(review4.getUserId())).collect(Collectors.toList());
                //2. 这里得到的parentReview是一个userid重复且相同的集合，需要根据userid过滤，最后集合只有一条数据
                List<ReviewVO> collect = parentReview.stream()
                        .collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ReviewVO::getUserId))))
                        .stream().collect(Collectors.toList());
                //3. 设置当前评论回复的评论的头像以及用户名称信息
                if(collect != null){
                    reviewVO.setParentUserName(collect.get(0).getUserName());
                    reviewVO.setParentHeadPortrait(collect.get(0).getHeadPortrait());
                }*/
                // 获取该子评论所回复评论的信息
                List<ReviewVO> parentReview
                        = reviews.stream()
                        // 获取所有的评论的回复id也就是父级id的userid，这样就可以获取到父级评论的信息
                        .filter(review4 -> reviewVO.getAnswerId().equals(review4.getId())).collect(Collectors.toList());
                reviewVO.setParentUserName(parentReview.get(0).getUserName());
                reviewVO.setParentReview(parentReview.get(0).getReview());
                reviewVO.setParentUserId(parentReview.get(0).getUserId());
                // 判断是否点赞
            }
            // 处理等级
            rootReview.setLevelStr(LevelUtils.levelToLevelName(rootReview.getLevel()));
            // 设置当前父评论的子评论
            rootReview.setSonReviewList(reviewList);
        }
        return Result.success(rootReviews);
    }


    /**
     * 提交评论
     *cc
     * @param review
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONResult submitReview(Review review, HttpServletRequest request) throws Exception{
        Post postEntity = postMapper.selectById(review.getPostId());
        if(postEntity == null){
            return Result.fail(ResultCode.POST_NOT_EXIST);
        }
        // 从jwt获取key
        User user = JWTConfig.getUser(request,null);
        if(StringUtils.isNotNull(user)){
            review.setUserId(Long.parseLong(String.valueOf(user.getId())));
            review.setUserName(user.getUserName());
            review.setReviewApproval(0);
            review.setTime(new Date());
            int insert = reviewMapper.insert(review);
            if(insert > 0){
                // 记录当前用户发布评论数
                User userEntity = userMapper.selectById(user.getId());
                userEntity.setReviewNum(userEntity.getReviewNum() + 1);
                userMapper.updateById(userEntity);
                // 记录帖子的评论数
                //Post postEntity = postMapper.selectById(params.getId());
                Post post = new Post();
                post.setId(review.getPostId());
                post.setReview(Integer.parseInt(postEntity.getReview()) + 1 + "");
                postMapper.updateById(post);

                boolean isAdd = LevelUtils.updateEmpiricalValue(user.getId(),ForumConstant.ADD_TYPE_REVIEW,false);
                if(isAdd) {
                    return Result.success(ResultCode.REVIEW_SUCCESS_ADD,Integer.parseInt(post.getReview()));
                } else{
                    return Result.success(ResultCode.REVIEW_SUCCESS,Integer.parseInt(post.getReview()));
                }
            } else {
                return Result.fail(ResultCode.DATA_WRITE_ERROR);
            }
        } else{
            return Result.fail(ResultCode.USER_TOKEN_ILLEGAL);
        }
    }

}
